﻿

#include "serialPort.h"

const int READ_TIMEOUT = 500;

serialPort::serialPort()
{
	bOpenCom = false;
}

serialPort::~serialPort()
{
	this->CloseCom();
}

bool serialPort::OpenCom(int Port)
{
	if (bOpenCom)
	{
		this->CloseCom();
		bOpenCom = false;
	}
	char szport[20];
	sprintf(szport,"\\\\.\\COM%d",Port);
	hComm = CreateFileA(szport,
		GENERIC_READ|GENERIC_WRITE,
		0,
		NULL,
		OPEN_EXISTING,
		FILE_FLAG_OVERLAPPED, //FILE_ATTRIBUTE_NORMAL|
		NULL);


	if (hComm == INVALID_HANDLE_VALUE)        return false;
	//设置缓冲区大小
	SetupComm(hComm, 1024, 1024);
	//设置超时
	COMMTIMEOUTS commtimeouts;
	commtimeouts.ReadIntervalTimeout = 30;
	commtimeouts.ReadTotalTimeoutConstant =2000;//固定超时
	commtimeouts.ReadTotalTimeoutMultiplier =50;//每个字符超时
	commtimeouts.WriteTotalTimeoutConstant =2000;
	commtimeouts.WriteTotalTimeoutMultiplier=50;
	SetCommTimeouts(hComm, &commtimeouts);


	DCB dcb;
	GetCommState(hComm, &dcb);
	dcb.fBinary = TRUE;
	//dcb.fParity = TRUE;
	dcb.BaudRate = CBR_9600;        // 波特率 9600
	dcb.ByteSize = 8;                // 8 位数据位
	dcb.Parity = NOPARITY;            // 无奇偶校验
	dcb.StopBits = ONESTOPBIT;        // 1 个停止位
	//
	/*dcb.fDsrSensitivity = FALSE;
	dcb.fOutxCtsFlow = FALSE;
	dcb.fOutxDsrFlow = FALSE;
	dcb.fOutX = FALSE;
	dcb.fInX = FALSE;*/

	SetCommState(hComm, &dcb );

	//清空缓存
	PurgeComm(hComm,PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_RXABORT | PURGE_TXABORT);
	//
	SetCommMask(hComm, EV_RXCHAR);

	bOpenCom = true;
	return bOpenCom;
}

void serialPort::CloseCom()
{
	if (!bOpenCom)    return;

	CloseHandle(hComm);
	hComm=NULL;

}

bool serialPort::WriteCom(const char *sendchar)
{
	//DWORD    BytesSent;
	//清空错误，使I/O正常进行
	ClearCommError(hComm,NULL,NULL);

	OVERLAPPED ov={0};
	ov.hEvent=CreateEventA(NULL,TRUE,FALSE,NULL);

	BOOL hr = WriteFile(hComm,                            // Handle to COMM Port
		sendchar,                        // Pointer to message buffer in calling finction
		strlen(sendchar),                        // Length of message to send
		NULL,                        // Where to store the number of bytes sent
		&ov);                    // Overlapped structure
	
	if(!hr && GetLastError() == ERROR_IO_PENDING)
	{
		DWORD rest=WaitForSingleObject(ov.hEvent,2000);
		CloseHandle(ov.hEvent);
		return rest==WAIT_OBJECT_0;
	}
	CloseHandle(ov.hEvent);
	return false;
}



bool serialPort::ReadCom(char * ReceiveData)
{
	//清空错误，使I/O正常进行
	//COMSTAT comstat;
	//DWORD errorflags;
	ClearCommError(hComm,NULL,NULL);
	//DWORD dwBytesRead=min(sizeof(ReceiveData),comstat.cbInQue);

	OVERLAPPED ov={0};
	ov.hEvent=CreateEventA(NULL,TRUE,FALSE,NULL);

	memset(ReceiveData,0,sizeof(ReceiveData));

	if (!ReadFile(hComm, ReceiveData, 200, NULL, &ov)) 
	{
		if (GetLastError() == ERROR_IO_PENDING)    
		{
			DWORD rest=WaitForSingleObject(ov.hEvent,2000);
			CloseHandle(ov.hEvent);
			return rest==WAIT_OBJECT_0;
		}
	}
	//PurgeComm(hComm, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
	CloseHandle(ov.hEvent);
	return false;
}